// Package dbsvc
// @Author: zhangdi
package dbsvc

import (
	"server/application/db/system/dbdto"
	"server/application/db/system/entity"
	"server/application/db/system/repository"
	"server/application/dto"
	"server/pkg/where"
	"server/setting"
	"sort"
)

// SysRoleCreate 创建
func SysRoleCreate(dtoCreate *dbdto.SysRoleCreate) (*dbdto.SysRoleInfo, error) {
	return repository.Create[
		entity.SysRole, dbdto.SysRoleCreate, dbdto.SysRoleInfo,
	](dtoCreate)
}

// SysRoleFindOne 查找
func SysRoleFindOne(wheres []*where.Condition) (*dbdto.SysRoleInfo, error) {
	return repository.FindOne[
		entity.SysRole, dbdto.SysRoleInfo,
	](wheres, false)
}

func SysRoleFindOneById(id uint) (*dbdto.SysRoleInfo, error) {
	wheres := where.FormatOne("id", "=", id)
	return repository.FindOne[
		entity.SysRole, dbdto.SysRoleInfo,
	](wheres, false)
}

// SysRoleFindList 查找列表
func SysRoleFindList(wheres []*where.Condition, extra *where.Extra) ([]*dbdto.SysRoleInfo, error) {
	return repository.FindList[
		entity.SysRole, dbdto.SysRoleInfo](wheres, extra, false)
}

// SysRoleSearch 搜索
func SysRoleSearch(wheres []*where.Condition, extra *where.Extra) ([]*dbdto.SysRoleInfo, int64) {
	total, err := SysRoleGetTotal(wheres)
	list := make([]*dbdto.SysRoleInfo, 0)
	if err != nil || total <= 0 {
		return list, 0
	}
	list, err = SysRoleFindList(wheres, extra)
	return list, total
}

// SysRoleUpdate 更新，字段可按规则传入，传入那个修改哪个
func SysRoleUpdate(wheres []*where.Condition, dtoUpdate *dbdto.SysRoleUpdate, columnsCfg ...string) error {
	return repository.Update[
		entity.SysRole, dbdto.SysRoleUpdate](wheres, dtoUpdate, columnsCfg...)
}

// SysRoleDelete 删除（deleted_at存在则是软删除）
func SysRoleDelete(wheres []*where.Condition) error {
	return repository.Delete[entity.SysRole](wheres, setting.UseSoftDelete)
}

// SysRoleGetTotal 获取总数
func SysRoleGetTotal(wheres []*where.Condition) (int64, error) {
	return repository.GetTotal[entity.SysRole](wheres)
}

// BuildRoleSonTree 以传入的节点构造一颗以传入节点id为根节点的树
func BuildRoleSonTree(sourceTree dto.RoleTreeSelect, newRootId uint) *dto.RoleTreeSelect {
	if sourceTree.Value == newRootId {
		// 当前节点是新树的根节点，复制当前节点
		newTree := &dto.RoleTreeSelect{
			Value:    sourceTree.Value,
			Label:    sourceTree.Label,
			Sort:     sourceTree.Sort,
			Children: sourceTree.Children,
		}

		return newTree
	}
	// 递归遍历当前节点的子节点
	for _, child := range sourceTree.Children {
		newTree := BuildRoleSonTree(child, newRootId)
		if newTree != nil {
			return newTree
		}
	}
	return nil
}

// GetSysRoleSonTree 获取一棵树某个子角色
func GetSysRoleSonTree(sourceTree []dto.RoleTreeSelect, roleIds []uint) []dto.RoleTreeSelect {
	sonTree := make([]dto.RoleTreeSelect, 0)
	for _, roleId := range roleIds {
		node := BuildRoleSonTree(sourceTree[0], roleId)
		if node != nil {
			sonTree = append(sonTree, *node)
		}
	}
	return sonTree
}

func BuildRoleMenuTree(menus []*dbdto.SysRoleInfo, parentId uint) []dto.SysRoleTree {
	var tree []dto.SysRoleTree
	for _, menu := range menus {
		if menu.ParentId == parentId {
			node := dto.SysRoleTree{
				ID:          menu.ID,
				Name:        menu.Name,
				Description: menu.Description,
				Sort:        menu.Sort,
				ParentId:    menu.ParentId,
				CreatedAt:   menu.CreatedAt,
			}

			if menu.ID != 0 {
				children := BuildRoleMenuTree(menus, menu.ID)
				node.Children = children
			}
			tree = append(tree, node)
		}
	}
	return tree
}

// SortRoleTree 按照sort对属性结果进行排序进行排序
func SortRoleTree(tree []dto.SysRoleTree) []dto.SysRoleTree {
	sort.Slice(tree, func(i, j int) bool {
		return tree[i].Sort > tree[j].Sort
	})
	for i := range tree {
		tree[i].Children = SortRoleTree(tree[i].Children)
	}
	return tree
}

// BuildRoleSelectTree 构造树形下拉选择列表
func BuildRoleSelectTree(menus []*dbdto.SysRoleInfo, parentId uint) []dto.RoleTreeSelect {
	var tree []dto.RoleTreeSelect
	for _, menu := range menus {
		if menu.ParentId == parentId {
			node := dto.RoleTreeSelect{
				Value:    menu.ID,
				Label:    menu.Name,
				Sort:     menu.Sort,
				Children: nil,
			}

			if menu.ID != 0 {
				children := BuildRoleSelectTree(menus, menu.ID)
				node.Children = children
			}
			tree = append(tree, node)
		}
	}
	return tree
}

// SortTreeSelect 按照sort对属性结果进行排序进行排序
func SortTreeSelect(tree []dto.RoleTreeSelect) []dto.RoleTreeSelect {
	sort.Slice(tree, func(i, j int) bool {
		return tree[i].Sort > tree[j].Sort
	})
	for i := range tree {
		tree[i].Children = SortTreeSelect(tree[i].Children)
	}
	return tree
}
